ARIA Tabs

Expected behaviors

The group of triggering elements should have only one tab stop, the arrow keys should move focus between each Tab in the group, pressing Enter or Space should expand the desired Tab panel, the expanded state should be toggled appropriately on the triggering element, and the expanded Tab panel should be rendered directly after the group of triggering elements in the tab order.

Though similar in both concept and execution to Tab controls, accordions are not the same. A Tab control has a series of grouped triggering elements that expand and collapse, the rendered content of which is inserted directly after the triggering element group when opened. The container element insertion point for all Tab control triggering elements is shared between them. Also, the group of triggering elements in a Tab control has only one tab stop. The arrow keys are then used to switch focus between each Tab, and the Enter or Space key is used to expand the desired Tab content panel.

In contrast, an Accordion has a series of triggering elements that expand and collapse, the rendered content of which is inserted directly after the triggering element when opened. The container element insertion points for Accordions are not shared. Also, all Accordion links appear in the tab order. The reason why ARIA attributes such as role="tablist" and role="tab" are not included within accordions, is because the insertion of inline content would place dynamic content sections within the same Tablist container, making it impossible to determine the order of nested Tab controls when present within the inserted content. The chosen implementation should always match the UI that it's being applied to, to prevent confusion.

The 4X ARIA Tab module automatically configures all required ARIA attributes and focus handling, in strict accordance with the ARIA specification.

The following attributes are handled automatically by the TabList module:

  • role=tablist
  • role=tab
  • aria-expanded
  • aria-selected
  • aria-controls
  • role=tabpanel
  • aria-labelledby
  • tabindex

Available attributes for the triggering element:

  • data-controls : The resource path and pointer to the ID attribute of the tab content container element.
  • data-root : The ID attribute of the container element where the tab content will be inserted when rendered. (This must not be inside the triggering element)
  • data-active : Specifies that the referenced tab node will open automatically. Only one tab node per group should include this attribute.
  • aria-disabled : When set to "true" on the triggering element, will automatically disable associated functionality.

Note: When dynamically disabling a triggering element, the 4X setDisabled() function should be used to set the disabled state of the triggering element. This will ensure proper background mapping.


$A.setDisabled(triggeringElement, boolean);

HTML syntax

<div class="tab-list">
  <button data-active data-root="root-container-id" data-controls="tab-panel-id-for-system" > SYSTEM </button>
  <button data-root="root-container-id" data-controls="tab-panel-id-for-network" > NETWORK </button>
</div>

<div id="root-container-id">

  <div id="tab-panel-id-for-system">
    Expandable content for the system section here. (Content visible by default via the data-active attribute on the triggering element.)
  </div>

  <div hidden id="tab-panel-id-for-network">
    Expandable content for the network section here. (Content hidden by default via the hidden attribute on the tab-panel.)
  </div>

</div>

IMPORTANT: The triggering element must not include any other active elements, otherwise these will not be accessible to non-sighted screen reader users.

When aria-disabled="true" is set on a tab triggering element, functionality for that panel will automatically be disabled.

JavaScript syntax

$A.setTab( domNodeListOrCSSSelectorForTriggeringElements , {
// Configure functionality key / value mappings
});
  • Module file: Tab.js
  • Requires: AccName.js, RovingTabIndex.js.
  • Recommended: Velocity.js, VelocityUI.js.

Parameters

  1. A DOM element or CSS selector to specify the triggering elements
  2. A configuration map to customize behaviors and options

Configuration

{

// Auto configure orientation using dynamic switching based on the visual layout of focusable elements.
// "off"=Inactive, "semi"=Switches between vertical and horizontal only, "full"= Switches between vertical, horizontal, and both when line-wrapping is detected.
autoSwitch: "full",

// Optionally extend the RTI instance with custom event handlers.
// For available options, view the RovingTabIndex help doc at "Help/Module Imports/Actions/RovingTabIndex".
extendRTI: {
// Optional event handlers.
},

// Optionally choose to track the browser history when each panel is opened.
// May be used to automatically open the same panel after the page is bookmarked.
// Requires that each tab triggering element include a unique id attribute.
    trackPage: false,

// Toggle the specified class name on the triggering element when hidden or shown.
    toggleClassName: "open",

// Optionally toggle the hidden attribute instead of inserting the tab panel when rendered.
    toggleHide: false,

// Preload markup in the background when using the Fetch API to load external content.
preload: true,

// Preload images in the background when using the Fetch API to load external content.
preloadImages: true,

// Optionally run a script after the tab panel finishes rendering.
afterRender: function(DC) {
// DC.container includes the rendered tab panel content.
},

// Optionally run a script after the tab panel is removed.
afterRemove: function(DC) {
// Do something.
},

/*
// Enable auto-rendering when the page loads.
// When true, the hash tag in the URL will automatically open the associated DC object.
// To render automatically, the hash tag must match the DC object id.
// To set a hash tag within the address bar, use the $A.setPage() function.
// For more details, view: Help/ARIA Development/Browser History and Permalinks
// Plus: Help/DC API/DC Object Configuration/Behaviors
trackPage: true,
afterRender: function(dc) {
$A.setPage(
dc.id,
$A.getText(dc.triggerNode) + " ARIA Tab - Apex 4X Technical Style Guide"
);
},
*/

// Optionally specify a render and remove animation effect for the tab panel.
// Requires the "Animate" module import to function, which is powered by Velocity.js.
// To ignore animation effects, delete the animate object declaration entirely from the setup script.
// View implementations within "Templates/Tabs" for practical animation usage examples.

style: { display: "none" }, // Set the initial state to hidden in prep for animation.

animate: {

onRender: function(dc, wrapper, next) {

// Specify the render animation effect, including the callback function statement to execute when the animation effect completes.
Velocity(wrapper, "transition.TYPE", {
// Velocity options here, plus the callback declaration after the animation completes.
complete: function() {
next(); // REQUIRED: next() must be executed so control is passed back to 4X for rendering.
}
});

},

onRemove: function(dc, wrapper, next) {

// Specify the removal animation effect, including the callback function statement to execute when the animation effect completes.
Velocity(wrapper, "transition.TYPE", {
// Velocity options here, plus the callback declaration after the animation completes.
complete: function() {
next(); // REQUIRED: next() must be executed so control is passed back to 4X for removal.
}
});

}

}

// (Additional DC API properties and methods can be declared here also to customize functionality and behavior)
// To view available options, reference the help docs located at: "Help/DC API/DC Object Configuration"

}

Programmatic control

// Get the DC object for the tab using its triggering element id.
var DC = $A("tabTriggerId");

// Open the tab panel manually.
DC.render(function() {
// Optionally do something after rendering completes.
});

// Close the tab manually.
DC.remove(function() {
// Optionally do something after removal completes.
});

// Additional DC API properties and methods can be applied here as well.
// To view available options, reference the help docs located at: "Help/DC API/DC Object Properties and Methods"